using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace AAAA
{
    /// <summary>
    /// windows 性能计数器操作
    /// 额外：
    /// windows 计数器结构， 一个计数器分类包含多个计数器， 某个计数器才能记录一个值
    /// </summary>
    public class PerformanceCounterHelper
    {
        /// <summary>
        /// 移除一个计数器分类
        /// T:System.ArgumentNullException:
        ///   categoryName 参数为 null。
        /// 
        /// T:System.ArgumentException:
        ///   categoryName 参数的语法无效。它可能包含反斜杠字符 ("\") 或者长度大于 80 个字符。
        /// 
        /// T:System.ComponentModel.Win32Exception:
        ///   对基础系统 API 的调用失败。
        /// 
        /// T:System.InvalidOperationException:
        ///   不能删除该类别，因为它不是自定义类别。
        /// 
        /// T:System.UnauthorizedAccessException:
        ///   以不具有管理特权的用户身份正在执行的代码尝试读取性能计数器。
        /// 
        /// </summary>
        /// <param name="CategoryName">计数器分类名称</param>
        public static void Remove(String CategoryName)
        {
            PerformanceCounterCategory mycat = new PerformanceCounterCategory(CategoryName);
            if (mycat != null)
            {
                try
                {
                    PerformanceCounterCategory.Delete(CategoryName);
                }
                catch (Exception ex)
                {
                    throw new Exception(String.Format("删除[{0}]性能计数器失败， 请尝试使用管理员运行该程序。错误信息：{1}", CategoryName, ex.Message));
                }
            }
        }
        /// <summary>
        /// 添加一个计数器
        ///  T:System.ArgumentException:
        ///    在 counterData 集合内指定的某计数器名称为 null 或空字符串 ("")。- 或 -在 counterData 集合内指定的某计数器已经存在。-
        ///    或 -counterName 参数的语法无效。它可能包含反斜杠字符 ("\") 或者长度大于 80 个字符。
        /// 
        ///  T:System.ArgumentNullException:
        ///    categoryName 参数为 null。
        /// 
        ///  T:System.InvalidOperationException:
        ///    该类别已存在于本地计算机上。- 或 -counterData 集合的布局对于基本计数器不正确。AverageCount64、AverageTimer32、CounterMultiTimer、CounterMultiTimerInverse、CounterMultiTimer100Ns、CounterMultiTimer100NsInverse、RawFraction、SampleFraction
        ///    或 SampleCounter 类型的计数器的后面必须紧跟基本计数器类型之一：AverageBase、MultiBase、RawBase 或 SampleBase。
        /// 
        ///  T:System.ComponentModel.Win32Exception:
        ///    对基础系统 API 的调用失败。
        /// 
        ///  T:System.UnauthorizedAccessException:
        ///    以不具有管理特权的用户身份正在执行的代码尝试读取性能计数器。
        /// </summary>
        /// <param name="CategoryName">计数器分类名称</param>
        /// <param name="CounterName">计数器名称</param>
        /// <param name="CounterDescription">计数器描述信息</param>

        public static void TryAdd(String CategoryName, String CounterName, String CounterDescription)
        {
            if (String.IsNullOrEmpty(CategoryName) || String.IsNullOrEmpty(CounterName))
            {
                return;
            }
            if (String.IsNullOrEmpty(CounterDescription))
            {
                CounterDescription = String.Format("该计数器的作用是:{0}-{1}", CategoryName, CounterName);
            }
            if (!PerformanceCounterCategory.Exists(CategoryName))
            {
                CounterCreationDataCollection ccdc = new CounterCreationDataCollection();

                CounterCreationData tmpSideAdapterTaskCounter = new CounterCreationData();
                tmpSideAdapterTaskCounter.CounterName = CounterName;
                tmpSideAdapterTaskCounter.CounterHelp = CounterDescription;
                tmpSideAdapterTaskCounter.CounterType = PerformanceCounterType.NumberOfItems32;

                ccdc.Add(tmpSideAdapterTaskCounter);
#pragma warning disable CS0618 // 类型或成员已过时
                try
                {
                    PerformanceCounterCategory.Create(CategoryName, CounterDescription, ccdc);
                }
                catch (Exception ex)
                {
                    throw new Exception(String.Format("添加[{0}-{1}]性能计数器失败， 请尝试使用管理员运行该程序。错误信息：{2}", CategoryName, CounterName, ex.Message));
                }
                
#pragma warning restore CS0618 // 类型或成员已过时
            }
        }
        /// <summary>
        /// 给某个计数器设置值, 平台不支持， 
        ///  T:System.InvalidOperationException:
        /// 您尝试设置计数器的原始值，但该计数器是只读的。- 或 -此实例未与性能计数器正确关联。- 或 -使用全局共享内存时，System.Diagnostics.PerformanceCounter.InstanceLifetime
        /// 属性设置为 System.Diagnostics.PerformanceCounterInstanceLifetime.Process。
        ///
        ///  T:System.ComponentModel.Win32Exception:
        ///    在访问系统 API 时发生错误。
        ///
        ///  T:System.PlatformNotSupportedException:
        ///    平台为 Windows 98 或 Windows Millennium Edition(Me)，这些平台不支持性能计数器。
        ///
        ///  T:System.UnauthorizedAccessException:
        ///    以不具有管理特权的用户身份正在执行的代码尝试读取性能计数器。
        /// </summary>
        /// <param name="CategoryName">计数器分类名称</param>
        /// <param name="CounterName">计数器名称</param>
        /// <param name="Value">计数器值</param>

        public static void SetValue(String CategoryName, String CounterName, long Value)
        {
            PerformanceCounterCategory mycat = new PerformanceCounterCategory(CategoryName);

            try
            {
                foreach (var item in mycat.GetCounters())
                {
                    if (item.CounterName == CounterName)
                    {
                        item.ReadOnly = false;
                        item.RawValue = Value;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("设置[{0}-{1}]性能计数器值失败， 请尝试使用管理员运行该程序。错误信息：{2}", CategoryName, CounterName, ex.Message));
            }
        }

    }
}
